package com.wen.common.ehcache;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.CacheConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.serializer.Serializer;

import java.io.*;
import java.nio.ByteBuffer;

/**
 * ehcache的缓存序列化的相关配置（未验证有效性）
 * <p>
 *
 * @author liwen <devinlive@163.com>
 * @version 1.0
 * @since 2023/05/05 14:36
 */
//@Configuration
public class EhcacheConfigurer {


    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
        EhCacheManagerFactoryBean factory = new EhCacheManagerFactoryBean();
        factory.setConfigLocation(new ClassPathResource("ehcache.xml"));
        factory.setShared(true);
        return factory;
    }

    @Bean
    public EhCacheCacheManager cacheManager(CacheManager cm) {
        return new EhCacheCacheManager(cm);
    }

    @Bean
    public CacheManagerCustomizer<EhCacheCacheManager> cacheManagerCustomizer() {
        return new CacheManagerCustomizer<EhCacheCacheManager>() {
            @Override
            public void customize(EhCacheCacheManager cacheManager) {
                // 获取默认的序列化器，然后替换为自定义的序列化器
//                DefaultSerializationProvider serializationProvider =
//                        ServiceLocator.locate(DefaultSerializationProvider.class);
//                Serializer<?> defaultSerializer = serializationProvider.createValueSerializer(Object.class, getClass().getClassLoader());
//                EhcacheConfigurer.CustomEhcacheSerializer customSerializer = new EhcacheConfigurer.CustomEhcacheSerializer();
//                serializationProvider.addSerializer("custom", customSerializer);
//
//                CacheManager myCacheManager = cacheManager.getCacheManager();
//                net.sf.ehcache.config.Configuration configuration = myCacheManager.getConfiguration();
//                CacheConfiguration cacheConfig = configuration.getCacheConfigurations().get("myCache");
//                cacheConfig.serializeValuesWith(serializationProvider.createKeySerializer(String.class.getClassLoader(), "custom"), serializationProvider.createValueSerializer(Object.class.getClassLoader(), "custom"));
            }
        };
    }

    private static class CustomEhcacheSerializer implements Serializer {
        private static final String CHARSET_NAME = "UTF-8";

        public ByteBuffer serialize(Object object) throws IllegalArgumentException {
            // 将 Object 对象转换为 JSON 格式的字符串
            ObjectMapper mapper = new ObjectMapper();
            String json;
            try {
                json = mapper.writeValueAsString(object);
            } catch (JsonProcessingException e) {
                throw new IllegalArgumentException(e);
            }

            // 使用 UTF-8 字符集将 JSON 字符串转换为字节数组
            byte[] bytes;
            try {
                bytes = json.getBytes(CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                throw new IllegalArgumentException(e);
            }

            // 将字节数组包装为 ByteBuffer 对象，并返回
            return ByteBuffer.wrap(bytes);
        }

        public Object read(ByteBuffer byteBuffer) throws IllegalArgumentException, ClassNotFoundException {
            // 从 ByteBuffer 中读取字节数组，并将其转换为 JSON 格式的字符串
            String json;
            try {
                byte[] bytes = new byte[byteBuffer.remaining()];
                byteBuffer.get(bytes);
                json = new String(bytes, CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                throw new IllegalArgumentException(e);
            }

            // 将 JSON 字符串转换为 Object 对象
            ObjectMapper mapper = new ObjectMapper();
            Object object;
            try {
                object = mapper.readValue(json, Object.class);
            } catch (IOException e) {
                throw new IllegalArgumentException(e);
            }
            return object;
        }

        @Override
        public boolean equals(Object o) {
            return getClass().equals(o.getClass());
        }

        @Override
        public void serialize(Object object, OutputStream outputStream) throws IOException {
            // 将 Object 对象转换为 JSON 格式的字符串
            ObjectMapper mapper = new ObjectMapper();
            String json;
            try {
                json = mapper.writeValueAsString(object);
            } catch (JsonProcessingException e) {
                throw new IOException(e);
            }

            ObjectOutputStream oos = new ObjectOutputStream(outputStream);
            oos.writeObject(json);
        }
    }

}
